package com.heng.service.Impl;

import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heng.constants.CouponStatusEnum;
import com.heng.constants.UserCouponUseStatusEnum;
import com.heng.dao.entity.Coupon;
import com.heng.dao.entity.UserCoupon;
import com.heng.dao.mapper.UserCouponMapper;
import com.heng.dto.UserCouponVO;
import com.heng.exception.BusinessException;
import com.heng.service.CouponService;
import com.heng.service.UserCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

// 用户优惠券Service实现
@Service
@Transactional
public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCoupon> implements UserCouponService {

    @Autowired
    private CouponService couponService;

    @Override
    public boolean receiveCoupon(Long userId, Long couponId) {
        // 1. 校验优惠券是否有效
        Coupon coupon = couponService.getValidCouponById(couponId);
        if (coupon == null) {
            throw new BusinessException("优惠券不存在或已失效");
        }

        // 2. 校验用户是否已超过领取次数
        Integer receiveCount = baseMapper.selectCountByUserAndCoupon(userId, couponId);
        if (receiveCount >= coupon.getLimitPerUser()) {
            throw new BusinessException("您已领取过该优惠券，无法重复领取");
        }

        // 3. 校验库存
        if (coupon.getSurplusStock() <= 0) {
            throw new BusinessException("优惠券库存不足");
        }

        // 4. 扣减优惠券库存（乐观锁防止超卖）
        LambdaUpdateChainWrapper<Coupon> updateWrapper = new LambdaUpdateChainWrapper<>(couponService.getBaseMapper())
                .eq(Coupon::getId, couponId)
                .eq(Coupon::getSurplusStock, coupon.getSurplusStock()) // 乐观锁条件
                .set(Coupon::getSurplusStock, coupon.getSurplusStock() - 1);
        boolean stockUpdated = updateWrapper.update();
        if (!stockUpdated) {
            throw new BusinessException("领取失败，请重试");
        }

        // 5. 新增用户优惠券记录
        UserCoupon userCoupon = UserCoupon.builder()
                .userId(userId)
                .couponId(couponId)
                .getTime(LocalDateTime.now())
                .useStatus(UserCouponUseStatusEnum.UNUSED.getCode())
                .build();
        return save(userCoupon);
    }

    @Override
    public List<UserCouponVO> getAvailableCoupons(Long userId, BigDecimal productPrice) {
        // 查询用户可用优惠券
        try {
            List<UserCoupon> userCoupons = baseMapper.selectAvailableCoupons(userId, productPrice);
            return userCoupons.stream().map(userCoupon -> {
                Coupon coupon = userCoupon.getCoupon();
                // 转换为VO返回
                return UserCouponVO.builder()
                        .id(userCoupon.getId())
                        .couponId(coupon.getId())
                        .couponName(coupon.getName())
                        .type(coupon.getType())
                        .typeDesc(coupon.getTypeDesc())
                        .amount(coupon.getAmount())
                        .fullPrice(coupon.getFullPrice())
                        .endTime(coupon.getEndTime())
                        .useStatus(userCoupon.getUseStatus())
                        .useStatusDesc(userCoupon.getUseStatusDesc())
                        .build();
            }).collect(Collectors.toList());
        } catch (Exception e) {
            System.err.println(e.getMessage());
            throw new BusinessException(e.getMessage());
        }

    }

    @Override
    public boolean useCoupon(Long userId, Long userCouponId, Long orderId) {
        // 校验用户优惠券是否存在且未使用
        UserCoupon userCoupon = getById(userCouponId);
        if (userCoupon == null || !userCoupon.getUserId().equals(userId) 
                || userCoupon.getUseStatus() != UserCouponUseStatusEnum.UNUSED.getCode()) {
            throw new BusinessException("优惠券不可用");
        }

        // 校验优惠券是否在有效期内
        Coupon coupon = couponService.getById(userCoupon.getCouponId());
        if (coupon == null || coupon.getStatus() != CouponStatusEnum.VALID.getCode()
                || coupon.getEndTime().isBefore(LocalDateTime.now())) {
            throw new BusinessException("优惠券已失效");
        }

        // 更新优惠券状态为已使用
        return baseMapper.updateUserCouponStatus(
                userCouponId,
                userId,
                UserCouponUseStatusEnum.USED.getCode(),
                LocalDateTime.now(),
                orderId
        );
    }
}